package ae.pcfc.cldos.online.web.services.security;

import java.io.IOException;
import java.util.Enumeration;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jboss.web.tomcat.security.login.WebAuthentication;
import org.springframework.beans.factory.annotation.Autowired;

import ae.pcfc.cldos.online.common.delegate.EncryptionDelegate;
import ae.pcfc.cldos.online.web.services.security.beans.LoginBean;

public class IEAuthenticationFilter implements Filter {

	private EncryptionDelegate encryptionDelegate;
	
	private static final String DEFAULT_REALM_NAME = "TKSOnlineServicesRealm";
	
	private String realmName = DEFAULT_REALM_NAME;
	
	public void setRealmName(String realmName) {
		this.realmName = realmName;
	}
	
	@Autowired
	protected SecurityService securityService;
	
	public void setEncryptionDelegate(EncryptionDelegate encryptionDelegate) {
		this.encryptionDelegate = encryptionDelegate;
	}
	
	public void destroy() {
		// TODO Auto-generated method stub
		
	}

	public void doFilter(ServletRequest req, ServletResponse resp,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest)req;
		HttpServletResponse response = (HttpServletResponse)resp;
		
		String userAgentHeader = request.getHeader("user-agent");
		Enumeration e = request.getHeaderNames();
		System.out.println(e);
		if(isIE(userAgentHeader) && !securityService.isAuthenticatedByRequest(request)){
			LoginBean loginBean = getBasicAuthenticationParameters(request);
			if(loginBean.isValidInfo()){
				WebAuthentication pwl = new WebAuthentication();
				pwl.login(loginBean.getLogin(), loginBean.getPassword());
				chain.doFilter(req, resp);
			} else {
				
				
				byte z = 0;
				byte[] msg = {
						(byte)'N',(byte)'T',(byte)'L',(byte)'M',(byte)'S',(byte)'S',(byte)'P',
						z , (byte)2,  z,z,z,z,z,z,z,(byte)40,z,z,z,(byte)1,(byte)130,z,z,z,(byte)2,(byte)2,(byte)2
						,z,z,z,z,z,z,z,z,z,z,z,z  
				};
				
				String headerValue = "NTLM";
				if(loginBean.isSspRequired()){
					headerValue+=" "+encryptionDelegate.base64encodeToString(msg).trim();
				}
				
				//headerValue = "NTLM";
				response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
				response.setHeader("WWW-Authenticate", headerValue);
				

				response.flushBuffer();
				return;
			}
		} else {
			chain.doFilter(req, resp);
		}
	}

	public void init(FilterConfig arg0) throws ServletException {
		// TODO Auto-generated method stub
		
	}

	private boolean isIE(String userAgent){
		return userAgent.indexOf("MSIE")!=-1;
	}
	
	private LoginBean getBasicAuthenticationParameters(HttpServletRequest request){
		LoginBean loginBean = new LoginBean();
		String authString = request.getHeader("Authorization");
		if(authString!=null){
			StringTokenizer st = new StringTokenizer(authString, " ");
			String scheme =null;
			try{
				scheme = st.nextToken();
			} catch (NoSuchElementException e) {
				//Do nothing
			}
			if(scheme!=null && scheme.equalsIgnoreCase("NTLM")){
				byte[] decodedAuthStr = null;
				try{
					decodedAuthStr = encryptionDelegate.base64decodeToByteArray(st.nextToken());
				}catch (Exception e) {
					// do nothing
				}
				if(decodedAuthStr[8]==1){
					loginBean.setSspRequired(true);
				}else if(decodedAuthStr!=null && decodedAuthStr.length>=9 && decodedAuthStr[8]==3){
					int off = 30;
					try{
						{
							int length = decodedAuthStr[off+9]*256 + decodedAuthStr[off+8];
							int offset = decodedAuthStr[off+11]*256 + decodedAuthStr[off + 10];
							loginBean.setLogin(new String(decodedAuthStr));
						}
						
						//loginBean.setPassword(st.nextToken());
					}catch (Exception e) {
						// TODO: handle exception
					}
					if(loginBean.getLogin()!=null && !loginBean.getLogin().isEmpty()
							&& loginBean.getPassword()!=null && !loginBean.getPassword().isEmpty()){
						loginBean.setValidInfo(true);
					}
				}
			}
		}
		return loginBean;
	}
}
